﻿/*
 *  PassBag is multi-platform software that securely manage/store passwords
 *  Copyright (C) <2009>  <Hugo Rodrigues PEREIRA>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *	
 *  You can find a copy of the GPLv3 at project <root directory>/gpl.txt
 *
 */

using System;
using System.Xml.Serialization;

namespace PassBag.Logic {

//CS0660: 'PassBag.Presentation.PasswordObject' defines operator == or operator != but does 
//not override Object.Equals(object o)
#pragma warning disable 0660

    /// <summary>
    /// The Passwork class contain the password item information
    /// </summary>
    [Serializable]
    public class PasswordObject : IComparable<PasswordObject>, IEquatable<PasswordObject>, ICloneable   {

        #region properties holder
        private Guid _id = Guid.Empty;
        private string _information = string.Empty;
        private string _title = string.Empty;
        private string _userName = string.Empty;
        private string _password = string.Empty;
        private string _url = string.Empty;
        private string _comment = string.Empty;
        private DateTime _lastModified = DateTime.MinValue;
        #endregion

        #region properties list
        /// <summary>
        /// Gets or sets the id.
        /// </summary>
        /// <value>The id.</value>
        [XmlIgnore]
        public Guid Id {
            get {
                return _id;
            }
            set {
                _id = value;
            }
        }

        /// <summary>
        /// Gets or sets the information.
        /// </summary>
        /// <value>The information.</value>
        public string Information {
            get {
                return _information;
            }
            set {
                _information = value;
            }
        }

        /// <summary>
        /// Gets or sets the title.
        /// </summary>
        /// <value>The title.</value>
        public string Title {
            get {
                return _title;
            }
            set {
                _title = value;
            }
        }

        /// <summary>
        /// Gets or sets the name of the user.
        /// </summary>
        /// <value>The name of the user.</value>
        public string UserName {
            get {
                return _userName;
            }
            set {
                _userName = value;
            }
        }

        /// <summary>
        /// Gets or sets the password.
        /// </summary>
        /// <value>The password.</value>
        public string Password {
            get {
                return _password;
            }
            set {
                _password = value;
            }
        }

        /// <summary>
        /// Gets or sets the URL.
        /// </summary>
        /// <value>The URL.</value>
        public string Url {
            get {
                return _url;
            }
            set {
                _url = value;
            }
        }

        /// <summary>
        /// Gets or sets the comment.
        /// </summary>
        /// <value>The comment.</value>
        public string Comment {
            get {
                return _comment;
            }
            set {
                _comment = value;
            }
        }
        /// <summary>
        /// Gets or sets the last modified.
        /// </summary>
        /// <value>The last modified.</value>
        [XmlIgnore]
        public DateTime LastModified {
            get {
                return _lastModified;
            }
            set {
                _lastModified = value;
            }
        }
        
        #endregion

        #region constructor'fromString
        /// <summary>
        /// Initializes a new instance of the <see cref="PasswordObject"/> class.
        /// </summary>
        public PasswordObject () {
            // Empty
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="PasswordObject"/> class.
        /// </summary>
        /// <param name="id">The guid.</param>
        public PasswordObject (Guid id) {
            this._id = id;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="PasswordObject"/> class.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="password">The password.</param>
        /// <param name="information">The information.</param>
        /// <param name="title">The title.</param>
        /// <param name="userName">Name of the user.</param>
        /// <param name="url">The URL.</param>
        /// <param name="comment">The comment.</param>
        /// <param name="lastModified">The last modified.</param>
        public PasswordObject (Guid id, string password, string information, string title, string userName, string url, string comment, DateTime lastModified) {
            this._id = id;
            this._information = information;
            this._password = password;
            this._title = title;
            this._userName = userName;
            this._url = url;
            this._comment = comment;
            this._lastModified = lastModified;
        }

        #endregion

        #region Public method
        public void Clear () {
            this._id = Guid.Empty;
            this._information = string.Empty;
            this._title = string.Empty;
            this._userName = string.Empty;
            this._password = string.Empty;
            this._url = string.Empty;
            this._comment = string.Empty;
            this._lastModified = DateTime.MinValue;
        } 
        #endregion

        #region IComparable<PasswordObject> Members

        /// <summary>
        /// Compares the class to another <see cref="PasswordObject"/>.
        /// </summary>
        /// <param name="obj">The obj.</param>
        /// <returns>An inteeger</returns>
        public int CompareTo (PasswordObject obj) {
            PasswordObject p2 = (PasswordObject)obj;
            return _id.CompareTo (p2.Id);
        }

        /// <summary>
        /// Compares the class to another <see cref="PasswordObject"/>.
        /// </summary>
        /// <param name="passObject">The passObject.</param>
        /// <param name="comparisonMethod">The comparison method.</param>
        /// <returns>An inteeger</returns>
        public int CompareTo (PasswordObject passObject, PasswordObjectComparer.ComparisonType comparisonMethod) {
            switch (comparisonMethod) {
                case PasswordObjectComparer.ComparisonType.UserName:
                    return _userName.ToString ().CompareTo (passObject._userName.ToString ());
                case PasswordObjectComparer.ComparisonType.Id:
                default:
                    return _id.CompareTo (passObject._id);
            }
        }
        #endregion

        #region IEquatable<PasswordObject> Members

        public bool Equals (PasswordObject other) {
            Guid theId = this.Id;
            Guid theOtherId = other.Id;

            return theId.Equals (theOtherId);
        }

        #endregion

        /// <summary>
        /// Implements the operator ==.
        /// </summary>
        /// <param name="emp1">The <see cref="PasswordObject"/> 1.</param>
        /// <param name="emp2">The <see cref="PasswordObject"/> 2.</param>
        /// <returns>The result of the operator.</returns>
        public static bool operator == (PasswordObject emp1, PasswordObject emp2) {
            if (object.ReferenceEquals (emp1, emp2))
                return true;
            if (object.ReferenceEquals (emp1, null))
                return false;
            if (object.ReferenceEquals (emp2, null))
                return false;

            return emp1.Equals (emp2);
        }

        /// <summary>
        /// Serves as a hash function for a particular type.
        /// </summary>
        /// <returns>
        /// A hash code for the current <see cref="T:System.Object"/>.
        /// </returns>
        public override int GetHashCode () {
            return this.Id.GetHashCode ();
        }

        /// <summary>
        /// Implements the operator !=.
        /// </summary>
        /// <param name="emp1">The <see cref="PasswordObject"/> 1.</param>
        /// <param name="emp2">The <see cref="PasswordObject"/> 2.</param>
        /// <returns>The result of the operator.</returns>
        public static bool operator != (PasswordObject emp1, PasswordObject emp2) {
            if (object.ReferenceEquals (emp1, emp2))
                return false;
            if (object.ReferenceEquals (emp1, null))
                return true;
            if (object.ReferenceEquals (emp2, null))
                return true;

            return !emp1.Equals (emp2);
        }

        #region ICloneable Members

        /// <summary>
        /// Creates a new object that is a copy of the current instance.
        /// </summary>
        /// <returns>
        /// A new object that is a copy of this instance.
        /// </returns>
        public object Clone () {
            return this.MemberwiseClone();
        }

        #endregion

    }
#pragma warning restore 0660
}
